package com.cazor.dg.app;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.net.url.UrlBuilder;
import cn.hutool.http.HttpRequest;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.cazor.common.utils.StringUtils;
import com.cazor.dg.common.DgConstants;
import com.cazor.dg.common.DgSysCacheService;
import com.cazor.dg.domain.*;
import com.cazor.dg.service.IDgHisDataReqListService;
import com.cazor.dg.service.IDgHisDataSensorService;
import com.cazor.dg.service.IDgParamDataSensorService;
import com.cazor.mg.domain.MgParamLog;
import com.cazor.mg.service.IMgParamLogService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

@Component
@Slf4j
public class AppHisDataService {

    private String endDateStr = "2024-01-12 08:30:00";
    DateTime endDate = DateTime.of(endDateStr, DatePattern.NORM_DATETIME_PATTERN);


    @Value("${dg.app.ip}")
    private String ip;

    @Value("${dg.app.port}")
    private int port;

    @Resource
    private IDgParamDataSensorService paramDataSensorService;
    @Resource
    private IMgParamLogService mgParamLogService;
    @Resource
    private DgSysCacheService dgSysCacheService;
    @Resource
    private AppService appService;
    @Resource
    private AppReqService appReqService;
    @Resource
    private IDgHisDataReqListService dgHisDataReqListService;
    @Resource
    private IDgHisDataSensorService dgHisDataSensorService;

    public void main() {
        // 查询已经完成的传感器数据
        List<DgHisDataSensor> list = dgHisDataSensorService.list();
        List<String> sensorIdList = CollectionUtil.size(list)<=0 ?
                new ArrayList<>() :
                list.stream().map(DgHisDataSensor::getSensorId).collect(Collectors.toList());

        // 获取所有有效的传感器基础数据列表
        List<DgParamDataSensor> paramDataSensorList = paramDataSensorService.getDgParamDataSensorList(null);
        int count = CollectionUtil.size(paramDataSensorList);
        if (count > 0) {
            int sc = CollectionUtil.size(sensorIdList);
            // 逐一遍历各个传感器
            for (DgParamDataSensor paramDataSensor : paramDataSensorList) {
                // 如果 已经处理过 则不再提交
                if (sc > 0 && sensorIdList.contains(paramDataSensor.getSensorId())) {
                    continue;
                }
                this.submitSensorDataHis(paramDataSensor);
            }
        }
    }

    public void submitSensorDataHis(DgParamDataSensor paramDataSensor) {
        String sensorId = paramDataSensor.getSensorId();
        if (StringUtils.isBlank(sensorId)) {
            log.warn("传感器 sendorId 为空");
            return;
        }
        DgDeviceSensor sensor = dgSysCacheService.getDeviceSensor(sensorId);
        DgConfigContentType configContentType = dgSysCacheService.getConfigContentType(sensor.getContentType());
        if (sensor == null || configContentType == null) {
            log.warn("传感器({})-获取到 DgDeviceSensor / DgConfigContentType 为 null", sensorId);
            return;
        }

        List<MgParamLog> paramLogList = mgParamLogService.selectMgParamLogHisList(sensorId, endDate);
        int count = CollectionUtil.size(paramLogList);
        if (count > 0) {
            // 排序
            paramLogList = paramLogList.stream()
                    .sorted(Comparator.comparing(MgParamLog::getReadDate)).collect(Collectors.toList());
            // 对于同一个传感器 多条监测数据 每6条数据分一组
            List<List<MgParamLog>> paramLogSplitList = ListUtil.split(paramLogList, 6);
            int successCount = 0, i = 0, j = CollectionUtil.size(paramLogSplitList);
            JSONObject requestParams = null, reqJson = null;
            List<DgHisDataReqList> dgHisDataReqList = new ArrayList<>();
            DgHisDataReqList req = null;


            for (List<MgParamLog> logList : paramLogSplitList) {
                int c = CollectionUtil.size(logList);
                requestParams = appService.initDeviceInstancesData(logList, paramDataSensor, sensor, configContentType);
                reqJson = this.DevDeviceParamDataSubmit(requestParams);
                if (reqJson!=null && reqJson.getInteger("code") == 200) {
                    successCount += c;
                } else {
                    req = new DgHisDataReqList();
                    req.setReq(requestParams.toString());
                    req.setResp(reqJson.toString());
                    req.setCode(reqJson.getInteger("code"));
                    req.setSuccess(reqJson.getBoolean("success")?"1":"0");
                    req.setSensorId(sensorId);
                    req.setCreateBy("sys");
                    req.setCreateTime(DateTime.now());
                    req.setUpdateBy(reqJson.getString("timestamp"));
                    req.setUpdateTime(DateTime.of(reqJson.getLong("timestamp")));
                    dgHisDataReqList.add(req);
                }
                i++;
                if( i%50 == 0) {
                    log.info("已经完成提交 {}/{} 组 数据",i, j );
                }
            }

            dgHisDataSensorService.saveRecords4Failed(paramDataSensor, count, successCount, dgHisDataReqList);
        } else {
            log.warn("传感器：{} -- 查询不到历史数据，不做提交", sensorId);
        }
        log.info("传感器:{} 完成历史数据提交", sensorId);
    }

    /**
     * 调用 山东接口
     * @param params
     * @return
     */
    public JSONObject DevDeviceParamDataSubmit(JSONObject params) {
        JSONObject rtn = null;
        String token = appReqService.getToken();
        if (CollectionUtil.isEmpty(params)) {
            return appReqService.createRtnJson(202, "监测数据为空，不能提交数据", false);
        }
        // 转换 form 数据
        Map<String, Object> paramsMap = new HashMap<>(2);
        paramsMap.put("deviceInstancesData", params.getString("deviceInstancesData"));
        paramsMap.put("deviceParamData", params.getString("deviceParamData"));
        if (StringUtils.isBlank(token)) {
            rtn = appReqService.createRtnJson(201, "获取令牌为空", false);
        } else {
            String url = UrlBuilder.of().setHost(ip).setPort(port).addPath(DgConstants.App.INSERT_DEV_DEVICE_PARAM_DATA_PATH).build();
            HttpRequest request = appReqService.createHttpRequest(url, token);
            String respStr = null;
            try {
                respStr = request.form(paramsMap).execute().body();
                rtn = JSON.parseObject(respStr);
            } catch (Exception e) {
                rtn = appReqService.createRtnJson(500, "新增 '监测数据' 请求异常" + e.getMessage(), false);
            }
        }
        return rtn;
    }
/*
    @Transactional(rollbackFor = Exception.class)
    public void saveRecords4Failed(DgParamDataSensor paramDataSensor, int dataCount, int successCount
        , List<DgHisDataReqList> dgHisDataReqList) {

        DgHisDataSensor sensor = new DgHisDataSensor();
        sensor.setDeviceId(paramDataSensor.getDeviceId());
        sensor.setSensorId(paramDataSensor.getSensorId());
//        sensor.setName(paramDataSensor.get);
        sensor.setDataCount(dataCount);
        sensor.setSuccessCount(successCount);
        sensor.setCreateBy("sys");
        sensor.setCreateTime(DateTime.now());
//        sensor.setUpdateBy();
//        sensor.setUpdateTime();

        if (CollectionUtil.isNotEmpty(dgHisDataReqList)) {
            dgHisDataReqListService.saveBatch(dgHisDataReqList);
        }

        dgHisDataSensorService.save(sensor);

    }*/

}
